<?php

namespace common\traits;

use Yii;
use ReflectionClass;
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
use common\helpers\ColorHelper;

/**
 * 类静态常量定义解析特性方法
 *
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
trait Constants {

    public static $constTranslateCategory = 'model';

    /**
     * 获取当前类的所有Const常量
     * @param string $prefix 常量前缀
     * @return array
     */
    public static function getConstants($prefix = '') {
        $reflectionClass = new ReflectionClass(get_called_class());
        $constants = $reflectionClass->getConstants();
        if (!$prefix || empty($constants)) {
            return $constants;
        }
        $constPrefix = rtrim(strtoupper($prefix), '_') . '_';
        $arrayReindexed = [];
        foreach ($constants as $key => $value) {
            if (strpos($key, $constPrefix) === 0) {
                $arrayReindexed[$key] = $value;
            }
        }
        return $arrayReindexed;
    }

    /**
     * 将常量名称格式化成语言包使用的标签
     * @param string|false $label 标签内容
     * @return string
     */
    protected static function formatConstLanguage($label = false) {
        if ($label === false) {
            return null;
        } else {
            $label = strtoupper($label);
        }
        $keywords = [
            'DISABLED',
            'PAYMODE',
            'FORBIDDEN',
            'ALLOW',
        ];
        foreach ($keywords as $prefix) {
            if (strpos($label, $prefix . '_') === 0) {
                return $label;
            }
        }
        $className = get_called_class();
        $parentClass = get_parent_class($className);
        while (strstr($parentClass, '\db\ActiveRecord') === false && strstr($parentClass, '\db\SequenceActiveRecord') === false) {
            $className = $parentClass;
            $parentClass = get_parent_class($className);
        }
        return basename(str_replace('\\', '/', $className)) . '_' . $label;
    }

    /**
     * 模型属性Const值选项列表
     * 
     * @param string $attribute 属性名称
     * @param bool $onlyLabel 是否仅使用标签
     * @return string
     */
    public static function attributeConstOptions($attribute, $onlyLabel = false) {
        $consts = self::getConstants($attribute);
        $data = [];
        foreach ($consts as $key => $vls) {
            $constName = self::formatConstLanguage($key);
            $translate = Yii::t(static::$constTranslateCategory, $constName);
            if (is_string($translate)) {
                $translate = [
                    'label' => $translate,
                ];
            }
            $translate['value'] = $vls;
            if (!$onlyLabel) {
                $data[] = $translate;
            } else {
                $data[$vls] = ArrayHelper::getValue($translate, 'label', $constName);
            }
        }
        return $data;
    }

    /**
     * 获取属性的Const名称值
     * @param string $attribute 属性名称
     * @return array
     */
    public static function attributeConstNames($attribute, $fill = null, $language = 'const/label') {
        $constants = self::getConstants($attribute);
        $arrayReindexed = [];
        foreach ($constants as $key => $vls) {
            $text = self::formatConstLanguage($key);
            $label = $language !== false ? Yii::t($language, $text) : $text;
            if (isset($arrayReindexed[$vls])) {
                $arrayReindexed[$vls] .= '|' . $label;
            } else {
                $arrayReindexed[$vls] = $label;
            }
            if ($fill !== null) {
                $arrayReindexed[$vls] .= $fill;
            }
        }
        return $arrayReindexed;
    }

    /**
     * 应用范围标签
     * Get member portlet panel.
     * @return string
     */
    public static function attributeConstName($attribute, $value) {
        $consts = self::getConstants($attribute);
        return array_search($value, $consts);
    }

    /**
     * 根据模型属性名称获取当前模型对应的Const常量语言标签名
     * @param string $attribute 属性名称
     * @return string
     */
    public function getAttributeConstName($attribute, $intact = true) {
        $value = null;
        if ($this->hasProperty($attribute)) {
            $value = $this->$attribute;
        }
        $constName = self::attributeConstName($attribute, $value);
        if ($constName === false) {
            return '';
        }
        return $intact ? self::formatConstLanguage($constName) : $constName;
    }

    /**
     * 应用范围标签
     * Get member portlet panel.
     * @return string
     */
    public static function markLabel($attribute, $value, $column = null) {
        $constMarkLabel = [
            'label' => $value,
            'value' => $value,
            'class' => 'dark',
        ];
        $prekey = static::attributeConstName($attribute, $value);
        if ($prekey !== false) {
            $translate = Yii::t(static::$constTranslateCategory, static::formatConstLanguage($prekey));
            if (is_string($translate)) {
                $constMarkLabel['label'] = $translate;
            } elseif (is_array($translate)) {
                $constMarkLabel = ArrayHelper::merge($constMarkLabel, $translate);
            }
        }
        if ($column !== null) {
            return ArrayHelper::getValue($constMarkLabel, $column, $value);
        }
        return $constMarkLabel;
    }

    /**
     * 应用范围标签
     * Get member portlet panel.
     * @return string
     */
    public function getMarkLabel($attribute, $value = null, $column = null) {
        if ($value === null) {
            $value = $this->$attribute;
        }
        return static::markLabel($attribute, $value, $column);
    }

    /**
     * ===========================================================================
     * 废弃内容
     * ===========================================================================
     */

    /**
     * 应用范围标签-废弃
     * Get member portlet panel.
     * @return string
     */
    public static function getMarksList($attribute) {
        return static::attributeConstOptions($attribute, true);
    }

    /**
     * 应用范围标签-废弃
     * Get member portlet panel.
     * @return string
     */
    public static function getMarksOptionList($attribute, $promote = false) {
        $consts = self::getConstants($attribute);
        $data = [];
        foreach ($consts as $key => $vls) {
            $translate = Yii::t('model', self::formatConstLanguage($key));
            if (!is_array($translate)) {
                $translate = [
                    'label' => $translate,
                ];
            }
            $translate['value'] = $vls;
            $data[$vls] = $translate;
        }
        if ($promote != false) {
            array_unshift($data, $promote);
        }
        return $data;
    }

    /**
     * 获取属性的Const名称值-废弃
     * @param string $attribute 属性名称
     * @return array
     */
    public static function getConstAttributeLabels($attribute, $fill = null, $language = 'const/label') {
        return static::attributeConstNames($attribute, $fill, $language);
    }

    /**
     * 应用范围标签-废弃
     * Get member portlet panel.
     * @return string
     */
    public static function getConstOptionsList($attribute) {
        $consts = self::getConstants($attribute);
        $data = [];
        foreach ($consts as $key => $vls) {
            $translate = Yii::t('model', self::formatConstLanguage($key));
            if (!is_array($translate)) {
                $translate = [
                    'label' => $translate,
                ];
            }
            $translate['value'] = $vls;
            $data[] = $translate;
        }
        return $data;
    }

    /**
     * 应用范围标签-废弃
     * Get member portlet panel.
     * @return string
     */
    public static function markLabel2($attribute, $value, $format = true, $options = [], $usecolor = false) {
        $consts = self::getConstants($attribute);
        $prekey = array_search($value, $consts);
        if ($format) {
            $label = self::formatConstLanguage($prekey);
            return [
                'text' => Yii::t('const/label', $label),
                'color' => Yii::t('const/hex', $label),
                'class' => Yii::t('const/class', $label),
            ];
        }
        return $prekey;
    }

}
